import { useAntdTable, useRequest, useUpdateEffect } from 'ahooks'
import { Button, Col, Form, Icon, Input, Popconfirm, Row, Spin, Typography } from 'antd'
import React, { useState } from 'react'
import ProcessDetail, { DataSourceMap } from '../ProcessDetail'
import EditProcessModal from '../EditProcessModal'
import SlickTable from '@/components/SlickTable'
import Space from '@/components/Space'
import { GlobalFormLayout } from '@/layouts/Form'
import request from '@/utils/request'
import IconLink from '@/components/IconLink'
import useModal from '@/hooks/UseModal'
import { getCurrentTenantId } from '@/utils/user'

function getTableData({ current, pageSize, ...rest }) {
  return request.post('/process/pageProcesses', {
    data: {
      current,
      pageSize,
      ...rest,
    },
  })
}

const { Text } = Typography

function ProcessList({ catalogId, form }) {
  const { getFieldDecorator, resetFields, getFieldsValue, setFieldsValue } = form
  const [selectedProcessId, setSelectProcessId] = useState()
  const [flag, setFlag] = useState(false)
  const [loading, setLoading] = useState(false)
  const [selectedRows, setSelectedRows] = useState([])

  const { loading: exportLoading, runAsync } = useRequest(() => request.get('/process/listProcessIds', {
    params: {
      parentCatalogId: catalogId,
      ...getFieldsValue(),
    },
  }), {
    manual: true,
  })

  const {
    tableProps: { pagination, ...restTableProps },
  } = useAntdTable(
    (query) => {
      const fieldsValue = getFieldsValue()
      return getTableData({ ...query, parentCatalogId: catalogId, ...fieldsValue })
    },
    {
      defaultPageSize: 10,
      refreshDeps: [flag],
    },
  )
  const refresh = () => {
    setFlag(!flag)
  }

  useUpdateEffect(() => {
    setFieldsValue(
      {
        processName: undefined,
        processCode: undefined,
      },
      () => {
        setSelectProcessId(undefined)
        refresh()
      },
    )
  }, [catalogId, setFieldsValue])

  const deleteProcess = (processCode) => {
    setLoading(true)
    request
      .post(`/process/deleteProcess?processCode=${processCode}`)
      .then(() => {
        refresh()
      })
      .finally(() => {
        setLoading(false)
      })
  }

  const { data, showModal, hideModal, visible } = useModal()

  const columns = [
    {
      dataIndex: 'processName',
      title: '流程名称',
      render: (processName, record) => (
        <a onClick={() => setSelectProcessId(record.processId)}>{processName}</a>
      ),
    },
    {
      dataIndex: 'processCode',
      title: '流程编码',
      render: text => <Text copyable>{text}</Text>,
    },
    {
      dataIndex: 'dataSourceType',
      title: '数据源类型',
      render: type => DataSourceMap[type],
    },
    {
      title: '操作',
      render: (_, record) => (
        <Space divider="vertical">
          <IconLink icon="container" onClick={() => setSelectProcessId(record.processId)}>
            详情
          </IconLink>
          <IconLink icon="edit" onClick={() => showModal(record)}>
            编辑
          </IconLink>
          <Popconfirm
            title={`确定要删除流程【${record.processName}】吗`}
            onConfirm={() => deleteProcess(record.processCode)}
          >
            <IconLink className="text-danger" icon="delete">
              删除
            </IconLink>
          </Popconfirm>
        </Space>
      ),
    },
  ]

  const handleBatchExport = (processIds) => {
    const formElement = document.createElement('form')
    formElement.style.display = 'display:none'
    formElement.method = 'post'
    formElement.action = `v1/process/batchExportVersionData?tenantId=${getCurrentTenantId()}`
    formElement.target = '_blank'

    const input = document.createElement('input')
    input.type = 'hidden'
    input.name = 'processIds'
    input.value = JSON.stringify(processIds)

    formElement.appendChild(input)
    document.body.appendChild(formElement)

    formElement.submit()

    formElement.removeChild(input)
    document.body.removeChild(formElement)
  }

  const exportCurrentCatalog = async () => {
    const processIds = await runAsync()
    handleBatchExport(processIds)
  }

  return (
    <>
      {selectedProcessId && (
        <ProcessDetail processId={selectedProcessId} goBack={() => setSelectProcessId(undefined)} />
      )}
      <div style={{ display: selectedProcessId ? 'none' : '' }}>
        <Form className="margin-bottom" {...GlobalFormLayout}>
          <Row gutter={16}>
            <Col span={6}>
              <Form.Item label="流程名称">
                {getFieldDecorator('processName')(
                  <Input onPressEnter={refresh} placeholder="请输入" />,
                )}
              </Form.Item>
            </Col>
            <Col span={6}>
              <Form.Item label="流程编码">
                {getFieldDecorator('processCode')(
                  <Input onPressEnter={refresh} placeholder="请输入" />,
                )}
              </Form.Item>
            </Col>
            <Col span={12}>
              <Space>
                <Button type="primary" onClick={refresh}>
                  查询
                </Button>
                <Button type="default" onClick={() => resetFields()}>
                  重置
                </Button>
                <Button type='default' icon='cloud-download' onClick={exportCurrentCatalog} loading={exportLoading}>
                  导出当前目录
                  <span style={{ marginLeft: 3, color: '#67d6ac' }}>({pagination.total})</span>
                </Button>
              </Space>
            </Col>
          </Row>
        </Form>
        <Spin spinning={loading}>
          <SlickTable
            pick="checkbox"
            rowKey="processId"
            columns={columns}
            data={{ pagination }}
            onSelectRow={setSelectedRows}
            selectedRows={selectedRows}
            onRow={(record) => {
              return {
                onDoubleClick: () => setSelectProcessId(record.processId),
              }
            }}
            extra={
              selectedRows.length
                ? (
                <Button onClick={() => handleBatchExport(selectedRows.map(row => row.processId))}>
                  <Icon type="cloud-download" />
                  批量导出
                </Button>
                  )
                : null
            }
            {...restTableProps}
          />
        </Spin>
      </div>
      <EditProcessModal
        visible={visible}
        onClose={hideModal}
        onOk={() => {
          hideModal()
          refresh()
        }}
        data={data}
      />
    </>
  )
}

export default Form.create()(ProcessList)
